# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
import json
import requests
from datetime import datetime


class ProductionWorkOrder(models.Model):
    _name = 'production.work.order'
    _description = '生产工单'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _order = 'create_date desc'

    # 基本信息
    name = fields.Char('工单名称', required=True, default='新工单', copy=False)
    wo_traceid = fields.Char('API ID', required=True, copy=False, index=True,
                             default=lambda self: self._generate_traceid())
    
    # 工单字段
    wo_domain = fields.Char('域', default='JLHT')
    wo_site = fields.Char('地点', default='1000')
    wo_part = fields.Char('零件号', index=True)  # 不设置required=True，由Python约束检查
    wo_line = fields.Char('生产线')  # 不设置required=True，由Python约束检查
    wo_emp = fields.Char('员工')  # 不设置required=True，由Python约束检查
    wo_shift = fields.Char('班次')
    wo_doc = fields.Char('文档号', compute='_compute_wo_doc', store=True)
    
    # 数量字段
    wo_qty_scrap = fields.Float('报废数量', digits=(12, 2), default=0.0)
    wo_qty_rjct = fields.Float('拒收数量', digits=(12, 2), default=0.0)
    wo_qty_comp = fields.Float('完工数量', digits=(12, 2), default=0.0)  # 不设置required=True，由Python约束检查
    
    # 生产信息
    wo_op = fields.Char('工序', required=True, default='99')
    wo_nbr = fields.Char('工单号')
    wo_lot = fields.Char('批次')
    wo_loc = fields.Char('完工库位', default='FG')
    wo_wkctr = fields.Char('工作中心')
    wo_bk_date = fields.Date('完工日期', required=True, default=fields.Date.today)
    wo_routing = fields.Char('工艺流程')
    wo_bom_code = fields.Char('产品结构')
    wo_rmks = fields.Text('备注')
    wo_type = fields.Char('工单类型')
    
    # 状态和追踪
    state = fields.Selection([
        ('draft', '草稿'),
        ('submitted', '已提交'),
        ('success', '成功'),
        ('failed', '失败'),
    ], string='状态', default='draft', required=True)
    
    # API响应信息
    api_response = fields.Text('API响应', readonly=True)
    api_return_status = fields.Char('返回状态', readonly=True)
    api_message = fields.Text('返回消息', readonly=True)
    api_call_time = fields.Datetime('API调用时间', readonly=True)
    
    # 扫描信息
    barcode_data = fields.Text('扫描数据')
    scan_time = fields.Datetime('扫描时间')
    barcode_scan_button = fields.Boolean(string="扫描条码", default=False)
    
    def _generate_traceid(self):
        """生成唯一的traceid"""
        return 'WO' + datetime.now().strftime('%Y%m%d%H%M%S')
    
    @api.depends('wo_traceid')
    def _compute_wo_doc(self):
        """自动生成文档号"""
        for record in self:
            record.wo_doc = record.wo_traceid or ''
    
    @api.constrains('wo_part', 'wo_line', 'wo_emp', 'name')
    def _check_required_fields(self):
        """检查必填字段（排除占位记录）"""
        for record in self:
            # 跳过占位记录（扫码界面用）
            if record.name == '扫码报工' or record.wo_part == 'PLACEHOLDER':
                continue
            
            # 对于实际工单，这些字段必填
            if not record.wo_part:
                raise ValidationError('零件号(wo_part)是必填字段！')
            if not record.wo_line:
                raise ValidationError('生产线(wo_line)是必填字段！')
            if not record.wo_emp:
                raise ValidationError('员工(wo_emp)是必填字段！')
    
    @api.model
    def create(self, vals):
        """创建记录时生成name"""
        if vals.get('name', '新工单') == '新工单':
            vals['name'] = f"工单-{vals.get('wo_part', '')}-{datetime.now().strftime('%Y%m%d%H%M%S')}"
        return super(ProductionWorkOrder, self).create(vals)
    
    def action_submit_to_qad(self):
        """提交数据到QAD API"""
        self.ensure_one()
        
        if self.state == 'success':
            raise UserError('该工单已成功提交，无需重复提交！')
        
        # 准备API数据
        api_data = self._prepare_qad_api_data()
        
        # 调用QAD API
        result = self._call_qad_api(api_data)
        
        if result.get('success'):
            self.write({
                'state': 'success',
                'api_response': json.dumps(result, ensure_ascii=False, indent=2),
                'api_return_status': result.get('data', {}).get('return_status', 'UNKNOWN'),
                'api_message': result.get('data', {}).get('message', ''),
                'api_call_time': fields.Datetime.now(),
            })
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': _('成功'),
                    'message': f'工单已成功提交到QAD！状态：{self.api_return_status}',
                    'type': 'success',
                    'sticky': False,
                }
            }
        else:
            self.write({
                'state': 'failed',
                'api_response': json.dumps(result, ensure_ascii=False, indent=2),
                'api_message': result.get('error', {}).get('message', '调用失败'),
                'api_call_time': fields.Datetime.now(),
            })
            raise UserError(f'提交失败：{self.api_message}')
    
    def _prepare_qad_api_data(self):
        """准备QAD API数据格式"""
        return {
            "dsBackflushMaster": {
                "dataid": self.wo_traceid,
                "traceid": self.wo_traceid,
                "ttwomstr": [{
                    "wo_domain": self.wo_domain or "",
                    "wo_site": self.wo_site or "",
                    "wo_part": self.wo_part or "",
                    "wo_line": self.wo_line or "",
                    "wo_emp": self.wo_emp or "",
                    "wo_shift": self.wo_shift or "",
                    "wo_doc": self.wo_doc or "",
                    "wo_qty_scrap": self.wo_qty_scrap or 0,
                    "wo_qty_rjct": self.wo_qty_rjct or 0,
                    "wo_qty_comp": self.wo_qty_comp or 0,
                    "wo_op": self.wo_op or "",
                    "wo_nbr": self.wo_nbr or "",
                    "wo_lot": self.wo_lot or "",
                    "wo_loc": self.wo_loc or "",
                    "wo_wkctr": self.wo_wkctr or "",
                    "wo_bk_date": self.wo_bk_date.strftime('%Y-%m-%d') if self.wo_bk_date else "",
                    "wo_routing": self.wo_routing or "",
                    "wo_bom_code": self.wo_bom_code or "",
                    "wo_rmks": self.wo_rmks or "",
                    "wo_type": self.wo_type or "",
                    "wo_traceid": self.wo_traceid,
                    "wo_dataid": 0
                }]
            }
        }
    
    def _call_qad_api(self, data):
        """调用QAD API接口"""
        import logging
        _logger = logging.getLogger(__name__)
        
        # 获取API配置
        endpoint = self.env['qad.api.endpoint'].search([
            ('endpoint_name', '=', 'backflush'),
            ('active', '=', True)
        ], limit=1)
        
        if not endpoint:
            raise UserError('未找到可用的QAD API接口配置！请先配置"backflush"接口。')
        
        server_config = endpoint.server_config_id
        if not server_config:
            raise UserError('API接口未配置服务器！')
        
        # 构建API URL（使用localhost进行内部调用）
        # 注意：不使用web.base.url，因为它可能是容器内部hostname，无法连接
        api_url = f"http://localhost:8069/api/qad/{server_config.server_code}/{endpoint.endpoint_name}"
        
        _logger.info(f"========== 开始调用QAD API ==========")
        _logger.info(f"API URL: {api_url}")
        
        # 直接使用固定的API Key进行测试
        api_key_value = '298a4b1128cb1bdb8da2bb87e0e9c11e9b82850f'
        
        # 记录原始数据
        _logger.info(f"原始数据类型: {type(data)}")
        _logger.info(f"原始数据: {data}")
        
        # 发送请求（使用正确的Authorization头）
        headers = {
            'Content-Type': 'application/json; charset=utf-8',
            'Authorization': f'Bearer {api_key_value}',  # 使用Bearer token格式
        }
        
        _logger.info(f"API Key (前8位): {api_key_value[:8]}...")
        
        _logger.info(f"请求头: {headers}")
        
        try:
            # 使用json.dumps手动序列化，确保UTF-8编码
            json_data = json.dumps(data, ensure_ascii=False)
            json_bytes = json_data.encode('utf-8')
            
            _logger.info(f"JSON字符串长度: {len(json_data)}")
            _logger.info(f"JSON字符串前200字符: {json_data[:200]}")
            _logger.info(f"编码后字节长度: {len(json_bytes)}")
            _logger.info(f"编码后字节前100: {json_bytes[:100]}")
            
            _logger.info(f"开始发送POST请求...")
            response = requests.post(
                api_url,
                data=json_bytes,
                headers=headers,
                timeout=30
            )
            
            _logger.info(f"响应状态码: {response.status_code}")
            _logger.info(f"响应头: {response.headers}")
            _logger.info(f"========== QAD API调用完成 ==========")
            
            return response.json()
        except Exception as e:
            _logger.error(f"========== QAD API调用异常 ==========")
            _logger.error(f"异常类型: {type(e).__name__}")
            _logger.error(f"异常信息: {str(e)}")
            import traceback
            _logger.error(f"异常堆栈:\n{traceback.format_exc()}")
            _logger.error(f"========== 异常信息结束 ==========")
            
            return {
                'success': False,
                'error': {
                    'code': 'REQUEST_ERROR',
                    'message': str(e)
                }
            }
    
    @api.model
    def process_barcode_scan_and_submit(self, barcode_data):
        """
        处理扫描的二维码数据，自动创建记录并提交到QAD
        用于移动端扫码报工，无需人工确认
        """
        import logging
        _logger = logging.getLogger(__name__)
        
        try:
            # 解析二维码数据（JSON格式）
            data = json.loads(barcode_data)
            
            _logger.info(f"========== 开始处理扫描数据 ==========")
            _logger.info(f"扫描数据: {data}")
            
            # 准备创建记录的数据
            create_vals = {
                'barcode_data': barcode_data,
                'scan_time': fields.Datetime.now(),
                'wo_domain': data.get('wo_domain', 'JLHT'),
                'wo_site': data.get('wo_site', '1000'),
                'wo_loc': data.get('wo_loc', 'FG'),
                'wo_op': data.get('wo_op', '99'),
            }
            
            # 从扫描数据中提取必填字段
            if 'wo_part' in data and data['wo_part']:
                create_vals['wo_part'] = str(data['wo_part']).strip()
            else:
                _logger.error(f"扫描数据缺少wo_part字段，数据: {data}")
                return {
                    'success': False,
                    'message': '扫描数据缺少必填字段：零件号(wo_part)！\n请检查二维码数据格式。'
                }
            
            if 'wo_line' in data and data['wo_line']:
                create_vals['wo_line'] = str(data['wo_line']).strip()
            else:
                _logger.error(f"扫描数据缺少wo_line字段")
                return {
                    'success': False,
                    'message': '扫描数据缺少必填字段：生产线(wo_line)！\n请检查二维码数据格式。'
                }
            
            if 'wo_emp' in data and data['wo_emp']:
                create_vals['wo_emp'] = str(data['wo_emp']).strip()
            else:
                _logger.error(f"扫描数据缺少wo_emp字段")
                return {
                    'success': False,
                    'message': '扫描数据缺少必填字段：员工(wo_emp)！\n请检查二维码数据格式。'
                }
            
            if 'wo_qty_comp' in data and data['wo_qty_comp']:
                try:
                    create_vals['wo_qty_comp'] = float(data['wo_qty_comp'])
                except (ValueError, TypeError):
                    _logger.error(f"完工数量格式错误: {data['wo_qty_comp']}")
                    return {
                        'success': False,
                        'message': '完工数量格式错误！\n请确保wo_qty_comp是数字。'
                    }
            else:
                _logger.error(f"扫描数据缺少wo_qty_comp字段")
                return {
                    'success': False,
                    'message': '扫描数据缺少必填字段：完工数量(wo_qty_comp)！\n请检查二维码数据格式。'
                }
            
            # 可选字段
            if 'wo_shift' in data:
                create_vals['wo_shift'] = data['wo_shift']
            if 'wo_nbr' in data:
                create_vals['wo_nbr'] = data['wo_nbr']
            if 'wo_lot' in data:
                create_vals['wo_lot'] = data['wo_lot']
            if 'wo_wkctr' in data:
                create_vals['wo_wkctr'] = data['wo_wkctr']
            if 'wo_bk_date' in data:
                create_vals['wo_bk_date'] = data['wo_bk_date']
            if 'wo_routing' in data:
                create_vals['wo_routing'] = data['wo_routing']
            if 'wo_bom_code' in data:
                create_vals['wo_bom_code'] = data['wo_bom_code']
            if 'wo_rmks' in data:
                create_vals['wo_rmks'] = data['wo_rmks']
            if 'wo_type' in data:
                create_vals['wo_type'] = data['wo_type']
            
            # 创建工单记录
            _logger.info(f"创建工单记录: {create_vals}")
            work_order = self.create(create_vals)
            _logger.info(f"工单创建成功，ID: {work_order.id}, traceid: {work_order.wo_traceid}")
            
            # 准备API数据
            api_data = work_order._prepare_qad_api_data()
            
            # 调用QAD API
            _logger.info(f"自动提交到QAD API...")
            result = work_order._call_qad_api(api_data)
            
            # 处理API返回结果
            if result.get('success'):
                return_status = result.get('data', {}).get('return_status', 'UNKNOWN')
                message = result.get('data', {}).get('message', '')
                
                work_order.write({
                    'state': 'success',
                    'api_response': json.dumps(result, ensure_ascii=False, indent=2),
                    'api_return_status': return_status,
                    'api_message': message,
                    'api_call_time': fields.Datetime.now(),
                })
                
                _logger.info(f"✅ 工单提交成功！return_status: {return_status}")
                
                return {
                    'success': True,
                    'message': f'报工成功！\n零件号：{work_order.wo_part}\n完工数量：{work_order.wo_qty_comp}\n状态：{return_status}',
                    'work_order_id': work_order.id,
                    'traceid': work_order.wo_traceid,
                    'return_status': return_status,
                }
            else:
                error_msg = result.get('error', {}).get('message', '调用失败')
                
                work_order.write({
                    'state': 'failed',
                    'api_response': json.dumps(result, ensure_ascii=False, indent=2),
                    'api_message': error_msg,
                    'api_call_time': fields.Datetime.now(),
                })
                
                _logger.error(f"❌ 工单提交失败：{error_msg}")
                
                return {
                    'success': False,
                    'message': f'报工失败！\n错误：{error_msg}',
                    'work_order_id': work_order.id,
                    'traceid': work_order.wo_traceid,
                }
            
        except json.JSONDecodeError:
            _logger.error('二维码数据格式错误，无法解析JSON')
            return {
                'success': False,
                'message': '二维码数据格式错误！\n请确保扫描的是有效的JSON格式数据。'
            }
        except Exception as e:
            _logger.error(f'处理扫描数据异常: {str(e)}')
            import traceback
            _logger.error(traceback.format_exc())
            return {
                'success': False,
                'message': f'处理失败：{str(e)}'
            }

